package com.bkhech.basicdemo;

import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.bytedeco.javacv.OpenCVFrameConverter;
import org.bytedeco.opencv.global.opencv_core;
import org.bytedeco.opencv.opencv_core.IplImage;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

/**
 * 解决手机录的视频有旋转角度，需要旋转处理的问题
 *
 * @author guowm
 * @date 2022/11/25
 */
public class VideoToolOfRRotate {
    public static void main(String[] args) throws Exception {
        randomGrabberFfmpegImage("C:\\Users\\guowm\\Videos\\bilibili-video.mp4", "C:\\Users\\guowm\\Videos\\", "VideoTool-bilibili-video-pic");
    }

    /**
     * 创建视频帧抓取工具
     *
     * @param filePath
     * @param targetFilePath
     * @param targetFileName
     * @throws Exception
     */
    public static void randomGrabberFfmpegImage(String filePath, String targetFilePath, String targetFileName) throws Exception {
        try (FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(filePath)) {
            grabber.start();

            //获取旋转角度信息(90度)
            String rotate = grabber.getVideoMetadata("rotate");

            // 获取视频时长， microseconds / 1000000 将单位转换为秒
            System.out.println("视频时长: " + grabber.getLengthInTime() / (1000 * 1000));
            //帧
            Frame frame;
            //i可以控制获取第几帧
            int i = 0;
            //一帧一帧去抓取视频图片，ff.grabImage(); 每次抓取下一帧
            while (i < 5) {
                //截图指定时间处的图片
//                grabber.setTimestamp(i * 1000000);
                frame = grabber.grabImage();
//                System.out.println(grabber.getTimestamp() / 1000000);
                //手机录的视频有旋转角度，需要旋转处理
                if (null != rotate && rotate.length() > 1) {
                    try (OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage()) {
                        IplImage src = converter.convert(frame);
                        frame = converter.convert(rotate(src, Integer.parseInt(rotate)));
                    }
                }
                //输出第几帧图片
                doExecuteFrame(frame, targetFilePath, targetFileName + i + i);
                i++;
            }
            grabber.stop();
        }

    }

    /**
     * 旋转角度
     */
    public static IplImage rotate(IplImage src, int angle) {
        IplImage img = IplImage.create(src.height(), src.width(), src.depth(), src.nChannels());
        opencv_core.cvTranspose(src, img);
        opencv_core.cvFlip(img, img, angle);
        return img;
    }

    public static void doExecuteFrame(Frame f, String targetFilePath, String targetFileName) throws IOException {
        if (null == f || null == f.image) {
            return;
        }

        try (Java2DFrameConverter converter = new Java2DFrameConverter()) {
            String imageMat = "jpg";
            String fileName = targetFilePath + File.separator + targetFileName + "." + imageMat;
            BufferedImage bi = converter.getBufferedImage(f);
            File output = new File(fileName);
            ImageIO.write(bi, imageMat, output);
        }

    }

}